<template>
  <el-dialog
    v-model="dialogVisible"
    :title="title"
    width="500px"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
  >
    <div class="register-container">
      <!-- 左侧表单 -->
      <el-form class="input-section" label-width="80px" label-position="top">
        <el-form-item label="从机 ID:">
          <el-input
            v-model="slaveId"
            class="left-form-item"
            controls-position="right"
            rules="[
              { required: true, message: '请输入从机 ID', trigger: 'blur' },
              { type: 'number', message: '请输入数字', trigger: ['blur', 'change'] }
            ]"
          />
        </el-form-item>

        <el-form-item label="起始地址:">
          <el-input
            v-model.number="address"
            class="left-form-item"
            controls-position="right"
          />
        </el-form-item>

        <el-form-item label="数量:">
          <el-input v-model="quantity" class="left-form-item" controls-position="right" />
        </el-form-item>

        <el-form-item label="类型:">
          <el-select v-model="dataType" class="left-form-item">
            <el-option
              v-for="dataType in InnerDecodeList"
              :key="dataType"
              :label="dataType"
              :value="dataType"
            />
          </el-select>
        </el-form-item>
      </el-form>

      <!-- 右侧表单 -->
      <el-form
        class="value-section"
        label-width="50px"
        style="height: 400px"
        label-position="right"
      >
        <el-scrollbar>
          <el-form-item
            v-for="(register, index) in registerList"
            :key="register.address"
            :label="`${register.address}  =`"
            label-width="70px"
          >
            <el-input v-model="register.value" controls-position="right" />
          </el-form-item>
        </el-scrollbar>
      </el-form>
    </div>

    <div class="button-group">
      <el-button @click="resetAll">全部置0</el-button>
      <el-button type="primary" @click="writeRegister(WriteMethod.Single)"
        >(06)循环写入寄存器
      </el-button>
      <el-button
        type="primary"
        class="write-btn"
        @click="writeRegister(WriteMethod.Multiple)"
      >
        (16)连续写入寄存器
      </el-button>
    </div>
  </el-dialog>
</template>

<script setup name="holdingRegister">
import { ref, watch } from "vue";
import {
  getRegisterCount,
  convertValue,
  InnerDecode,
  InnerDecodeList,
  ModbusFunctionCode,
  RegisterType,
  WriteMethod,
} from "@/types/register.ts";
import { writeRegister as writeRegisterApi } from "@/api/slaveApi.ts";
import { ElMessage } from "element-plus";

const props = defineProps({
  deviceName: {
    type: String,
    required: true,
  },
  slaveId: {
    type: Number,
    required: true,
  },
});

const dialogVisible = ref(false);
const title = ref("06/16：写保持寄存器");
const slaveId = ref(1);
const address = ref(0);
const registerList = ref([]);
const quantity = ref(10);
const dataType = ref(InnerDecode.SignedShort);

watch(
  [() => quantity.value, () => address.value, () => dataType.value],
  () => {
    const registerSize = getRegisterCount(dataType.value);
    const actualQuantity = Math.ceil(quantity.value / registerSize);

    // 存储旧的 registerList 的原始 value
    const oldRawValues = {};
    registerList.value.forEach((item) => {
      oldRawValues[item.address] = item.value;
    });

    // 改为字典数组结构，每个元素包含 address 和 value
    registerList.value = Array.from({ length: actualQuantity }, (_, i) => {
      const addr = address.value + i * registerSize;
      const oldRawValue = oldRawValues[addr];
      // 如果存在旧值，根据 dataType 转换；否则使用默认值
      const newValue =
        oldRawValue !== undefined
          ? convertValue(oldRawValue, dataType.value)
          : convertValue(0, dataType.value);
      return {
        address: addr,
        value: newValue,
      };
    });
  },
  { immediate: true }
);

const resetAll = () => {
  for (const register of registerList.value) {
    register.value = 0;
  }
};

const writeRegister = async (writeMethod) => {
  const values = registerList.value.map((item) => item.value);
  let isSuccess = false;
  if (writeMethod === WriteMethod.Single) {
    isSuccess = await writeRegisterApi(
      props.deviceName,
      slaveId.value,
      RegisterType.holding,
      address.value,
      dataType.value,
      values,
      ModbusFunctionCode.WRITE_HOLDING_REGISTERS
    );
  } else {
    isSuccess = await writeRegisterApi(
      props.deviceName,
      slaveId.value,
      RegisterType.holding,
      address.value,
      dataType.value,
      values,
      ModbusFunctionCode.WRITE_MULTIPLE_REGISTERS
    );
  }

  if (isSuccess) {
    ElMessage({
      type: "success",
      message: `写入寄存器成功!`,
      duration: 3000,
    });
  }
};

const openDialog = () => {
  dialogVisible.value = true;
};

const closeDialog = () => {
  dialogVisible.value = false;
};

// 如果需要从父组件控制对话框显示
defineExpose({
  openDialog,
  closeDialog,
});
</script>

<style scoped>
.register-container {
  display: flex;
  justify-content: space-between;
  gap: 30px;
  margin: 10px 10px 10px 10px;
}

.left-form-item {
  width: 200px;
}

.input-section {
  flex: 1;
  min-width: 200px;
}

.value-section .el-form-item {
  margin-bottom: 10px;
}

.button-group {
  display: flex;
  justify-content: flex-end;
  margin-top: 20px;
  gap: 10px;
}

/* 使用深度选择器穿透scoped限制 */
:deep(.write-btn) {
  background-color: #ff6d33 !important;
  border-color: #ff6d33 !important;
  color: white !important;
}

/* 处理悬停状态 */
:deep(.write-btn:hover) {
  background-color: #ff8d66 !important;
  border-color: #ff8d66 !important;
}

/* 处理点击状态 */
:deep(.write-btn:active) {
  background-color: #e65c2b !important;
  border-color: #e65c2b !important;
}
</style>
